//
//  HttpUtils.m
//  Weike
//
//  Created by leirz on 14-3-12.
//  Copyright (c) 2014年 winupon. All rights reserved.
//

#import "HttpRequest1.h"
#import "AppUtils.h"
#import "DateUtil.h"
#import "Toast.h"
#import "AFHTTPRequestOperationManager.h"
#import "AppDelegate.h"
#import "ServerMng.h"
#import "NSDictionary+Ext.h"
#import "FileUtil.h"


#define REQUESR_ERROR_CODE_TOKEN_INVALID @"2-3"  //token失效
#define REQUESR_ERROR_CODE_USER_KICKED @"2-10"   //被踢
#define REQUESR_ENABLE_LOG YES


@interface HttpRequest1()
{
    AFHTTPRequestOperationManager *operationManager;
    UIApplication *application;
    NSString *appVersion;
}
@end

@implementation HttpRequest1

- (id)init
{
    self = [super init];
    if (self) {
        operationManager = [AFHTTPRequestOperationManager manager];
        NSURLCache *urlCache = [NSURLCache sharedURLCache];
        [urlCache setMemoryCapacity:5 * 1024 * 1024];// 设置缓存大小为5M
        [NSURLCache setSharedURLCache:urlCache];
    }
    return self;
}

+ (HttpRequest1 *)sharedHttpRequest
{
    static HttpRequest1 *request = nil;
    static dispatch_once_t pred = 0;
    dispatch_once(&pred, ^{
        request = [[self alloc] init];
    });
    return request;
}

- (void)syncGet:(NSString *)url completion:(void (^)(BOOL, NSString *))completion
{
    [self syncRequest:url method:@"GET" params:nil completion:completion];
}

- (void)syncPost:(NSString *)url params:(NSDictionary *)params completion:(void (^)(BOOL, NSString *))completion
{
    [self syncRequest:url method:@"POST" params:params completion:completion];
}

- (void)syncRequest:(NSString *)url method:(NSString *)method params:(NSDictionary *)params completion:(void (^)(BOOL, NSString *))completion
{
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:url]];
    [request setHTTPMethod:method];
    if ([method isEqualToString:@"POST"]) {
        [request setHTTPBody:[[AppUtils toJSONString:params] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
    }
    NSHTTPURLResponse *urlResponse = nil;
    NSError *error = nil;
    NSData *recervedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
    NSString *results = [[NSString alloc] initWithBytes:[recervedData bytes] length:[recervedData length] encoding:NSUTF8StringEncoding];
    if (error != nil) {
        completion(NO, nil);
    } else {
        completion(YES, results);
    }
}

- (void)post:(NSString *)url params:(NSDictionary *)params complete:(void(^)(BOOL success, NSDictionary *result))complete
{
    [self sendRequest:url method:@"POST" params:params useCache:NO complete: complete errors:YES];
}

- (void)post:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL, NSDictionary *))complete errors:(BOOL)errors
{
    [self sendRequest:url method:@"POST" params:params useCache:NO complete: complete errors:errors];
}

- (void)get:(NSString *)url params:(NSDictionary *)params complete:(void(^)(BOOL success, NSDictionary *result))complete
{
    [self sendRequest:url method:@"POST" params:params useCache:NO complete: complete errors:YES];
}

- (void)get:(NSString *)url params:(NSDictionary *)params useCache:(BOOL)useCache complete:(void(^)(BOOL success, NSDictionary *result))complete
{
    [self sendRequest:url method:@"POST" params:params useCache:useCache complete: complete errors:YES];
}

- (void)sendRequest:(NSString *)url
             method:(NSString *)method
             params:(NSDictionary *)params1
           useCache:(BOOL)useCache
           complete:(void(^)(BOOL success, NSDictionary *result))complete
             errors:(BOOL)errors
{
    url = [self getRequestUrl:url];
    NSDictionary *requestparam = [[self getRequestParams:params1] copy];
    
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    NSMutableURLRequest *request = [serializer requestWithMethod:method URLString:url parameters:requestparam error:nil];
    // 设置请求超时时间(秒)
    NSUInteger timeout = [AppUtils toInteger:[params1 objectForKey:REQUEST_TIME_OUT]];
    timeout = timeout == 0 ? 30 : timeout;
    [request setTimeoutInterval:timeout];
    
    //设置固定的头部header信息-signkey
    NSString *signKey = [self getSignInfo:params1];
    
    //    [request setValue:signKey forHTTPHeaderField:@"X-JEECG-SIGN"];
    
    void(^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {
        if (REQUESR_ENABLE_LOG) {
            DSLog(@"获取的接口数据是====%@",[AppUtils toJSONString:responseObject]);
        }
        NSDictionary *resultDict = [NSDictionary changeType:responseObject];
        BOOL *success = [AppUtils toString:resultDict[@"success"]].boolValue;
        
        if (!success) {
            complete(NO, resultDict);
            [self handlerSuccess:resultDict];
             } else {
            complete(YES, resultDict);
        }
    };
    void(^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {
        complete(NO, nil);
    };
    AFHTTPRequestOperation *operation = nil;
    if (useCache) {
        [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
        operation = [self cacheOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];
    } else {
        operation = [operationManager HTTPRequestOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];
    }
    [operationManager.operationQueue addOperation:operation];
}


- (NSMutableDictionary *)getRequestParams:(NSDictionary *)params
{
    NSMutableDictionary *requestParams = [[NSMutableDictionary alloc] init];
    if(params==nil){
        params = [NSMutableDictionary dictionary];
    }
    [requestParams setValue:[AppUtils toJSONString:params] forKey:@"body"];
    return requestParams;
}

- (AFHTTPRequestOperation *)cacheOperationWithRequest:(NSURLRequest *)request
                                              success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                              failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {
    AFHTTPRequestOperation *operation = [operationManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject){
        NSCachedURLResponse *response = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
        // 将数据存入缓存
        response = [[NSCachedURLResponse alloc] initWithResponse:operation.response data:operation.responseData userInfo:nil storagePolicy:NSURLCacheStorageAllowed];
        [[NSURLCache sharedURLCache] storeCachedResponse:response forRequest:request];
        success(operation, responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error){
        if (error.code == kCFURLErrorNotConnectedToInternet) {
            NSCachedURLResponse *response = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
            if (response != nil && [[response data] length] > 0) {
                success(operation, response.data);
            } else {
                failure(operation, error);
            }
        } else {
            failure(operation, error);
        }
    }];
    return operation;
}

- (AFHTTPRequestOperation *)upload:(NSString *)url
                            params:(NSDictionary *)params
                             files:(NSArray *)files
                          complete:(void (^)(BOOL, NSDictionary *))complete
{
    return [self upload:url params:params files:files quality:ImageUploadQualityAuto process:nil complete:complete];
}

- (AFHTTPRequestOperation *)upload:(NSString *)url
                            params:(NSDictionary *)params
                             files:(NSArray *)files
                           quality:(ImageUploadQuality)quality
                          complete:(void (^)(BOOL, NSDictionary *))complete
{
    return [self upload:url params:params files:files quality:quality process:nil complete:complete];
}

- (AFHTTPRequestOperation *)upload:(NSString *)url
                            params:(NSDictionary *)params
                             files:(NSArray *)files
                           process:(void (^)(long long, long long))process
                          complete:(void (^)(BOOL, NSDictionary *))complete
{
    return [self upload:url params:params files:files quality:ImageUploadQualityAuto process:process complete:complete];
}

- (AFHTTPRequestOperation *)upload:(NSString *)urlStr
                            params:(NSDictionary *)params1
                             files:(NSArray *)files
                           quality:(ImageUploadQuality)quality
                           process:(void (^)(long long, long long))process
                          complete:(void (^)(BOOL, NSDictionary *))complete
{
    NSLog(@"\nurl:%@\n%@\n",urlStr,params1);
    NSString *url = [self getRequestUrl:urlStr];
    NSString *signKey = [self getSignInfo:params1];
    NSDictionary *requestparam = [[self getRequestParams:params1] copy];
    
    NSString *uploadName = params1[@"uploadName"]; // 服务端接收参数名称
    if (uploadName == nil) {
        uploadName = @"files";
    } else {
        uploadName = params1[@"uploadName"];
    }
    CGFloat imageQuality = [self getImageQuality:quality];
    
    
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:url parameters:requestparam constructingBodyWithBlock:^(id<AFMultipartFormData> formData){
        for (NSDictionary *fileItem in files) {
            id value = [fileItem objectForKey:@"file"]; //支持四种数据类型:NSData、UIImage、NSURL、NSString
            NSString *fileName = [fileItem objectForKey:@"name"]; //文件名称
            NSString *mimeType = [fileItem objectForKey:@"type"]; // 文件类型
            mimeType = mimeType ? mimeType : @"image/jpeg";// @"multipart/form-data";
            if ([value isKindOfClass:[NSData class]]) {
                [formData appendPartWithFileData:value name:uploadName fileName:fileName mimeType:mimeType];
            } else if ([value isKindOfClass:[UIImage class]]) {
                [formData appendPartWithFileData:UIImageJPEGRepresentation(value, imageQuality) name:uploadName fileName:fileName mimeType:mimeType];
            } else if ([value isKindOfClass:[NSURL class]]) {
                [formData appendPartWithFileURL:value name:uploadName fileName:fileName mimeType:mimeType error:nil];
            } else if ([value isKindOfClass:[NSString class]]) {
                NSString *filePath = (NSString *)value;
                NSURL *url = nil;
                if (![filePath hasPrefix:@"file://"]) {
                    url = [NSURL fileURLWithPath:filePath];
                } else {
                    url = [NSURL URLWithString:filePath];
                }
                [formData appendPartWithFileURL:url name:uploadName fileName:fileName mimeType:mimeType error:nil];
            }
        }
    } error:nil];
    [request setTimeoutInterval:180];// 3分钟
    //设置固定的头部header信息-signkey
    [request setValue:signKey forHTTPHeaderField:@"X-JEECG-SIGN"];
    
    AFHTTPRequestOperation *operation = nil;
    operation = [operationManager HTTPRequestOperationWithRequest:request success:^ (AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"\n获取的接口数据是====%@",[AppUtils toJSONString:responseObject]);
        BOOL status = [AppUtils toString:responseObject[@"success"]].boolValue;
        if (status) {
            complete(YES, responseObject);
        } else {
            if([self handlerSuccess:responseObject]){
                complete(NO, responseObject);
            }
        }
    } failure:^ (AFHTTPRequestOperation *operation, NSError *error) {
        complete(NO, nil);
    }];
    if (process) {
        [operation setUploadProgressBlock:^(NSUInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
            process(totalBytesWritten, totalBytesExpectedToWrite);
        }];
    }
    [operation start];
    return operation;
}

- (CGFloat)getImageQuality:(ImageUploadQuality)quality
{
    CGFloat value = 0;
    switch (quality) {
        case ImageUploadQualityAuto:{
            if ([AppUtils getNetWorkType] == NetTypeWiFi) {
                value = 0.6;
            } else {
                value = 0.4;
            }
            break;
        }
        case ImageUploadQualityHigh:
            value = 0.8;
            break;
        case ImageUploadQualityMiddle:
            value = 0.6;
            break;
        case ImageUploadQualityLower:
            value = 0.4;
            break;
    }
    return value;
    
}

- (AFHTTPRequestOperation *)download:(NSString *)url
                              params:(NSDictionary *)params
                            filePath:(NSString *)filePath
                            complete:(void (^)(BOOL, NSDictionary *))complete
{
    return [self download:url params:params filePath:filePath process:nil complete:complete];
}
- (AFHTTPRequestOperation *)download:(NSString *)url
                              params:(NSDictionary *)params
                            filePath:(NSString *)filePath
                             process:(void (^)(long long, long long))process
                            complete:(void (^)(BOOL, NSDictionary *))complete
{
    return [self download:url params:params filePath:filePath userInfo:nil process:process complete:^(BOOL success, NSDictionary *result, NSDictionary *userInfo) {
        complete(success, result);
    }];
}

- (AFHTTPRequestOperation *)download:(NSString *)url
                              params:(NSDictionary *)params
                            filePath:(NSString *)filePath
                            userInfo:(NSDictionary *)userInfo
                             process:(void (^)(long long, long long))process
                            complete:(void (^)(BOOL, NSDictionary *, NSDictionary *))complete
{
    
    if([FileUtil isFileDir:filePath]){
        [Toast makeText:@"文件保存地址错误"];
        return nil;
    }
    
    NSMutableDictionary *requestParams = [NSMutableDictionary dictionary];
    if(params){
        [requestParams setDictionary:params];
    }
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    NSMutableURLRequest *request = [serializer requestWithMethod:@"GET" URLString:url parameters:requestParams error:nil];
    [request setTimeoutInterval:300];// 5分钟
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer.acceptableContentTypes = nil;
    operation.userInfo = userInfo;
    NSString *tmpPath = [filePath stringByAppendingString:@".tmp"];
    operation.outputStream = [[NSOutputStream alloc] initToFileAtPath:tmpPath append:NO];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSArray *mimeTypeArray = @[@"text/html", @"application/json"];
        NSError *moveError = nil;
        if ([mimeTypeArray containsObject:operation.response.MIMEType]) {
            responseObject = [NSData dataWithContentsOfFile:tmpPath];
            responseObject = [NSJSONSerialization JSONObjectWithData:responseObject options:2 error:nil];
            [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
        } else {
            [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
            [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:&moveError];
        }
        if (!moveError) {
            complete(YES, responseObject, operation.userInfo);
        } else {
            complete(NO, responseObject, operation.userInfo);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
        complete(NO, nil, operation.userInfo);
    }];
    if (process) {
        [operation setDownloadProgressBlock:^(NSUInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) {
            //            DSLog(@"download process: %.2d%% (%ld/%ld)", 100 * totalBytesRead / totalBytesExpectedToRead, (long)totalBytesRead, (long)totalBytesExpectedToRead);
            process(totalBytesRead, totalBytesExpectedToRead);
        }];
    }
    [operation start];
    return operation;
}


/**
 * 获取signkey
 */
- (NSString *)getSignInfo:(NSDictionary *)params
{
    if(params==nil){
        params = [NSMutableDictionary dictionary];
    }
    
    NSMutableString *signStr = [NSMutableString string];
    //    NSArray *keys = [params allKeys];
    //    keys = [keys sortedArrayUsingSelector:@selector(compare:)];
    //    if([AppUtils isNotEmptyArray:keys]){
    //        for(NSString *key in keys){
    //            [signStr appendString:[NSString stringWithFormat:@"%@=%@&",key,params[key]]];
    //        }
    //    }
    [signStr appendString:[NSString stringWithFormat:@"body=%@&",[AppUtils toJSONString:params]]];
    
    [signStr appendString:[NSString stringWithFormat:@"key=%@",SIGN_KEY]];
    NSString * signKey = [AppUtils md5:[NSString stringWithFormat:@"%@",signStr]];
    //    NSLog(@"签名串signKey= %@",signKey);
    return signKey;
}

- (NSString *)getRequestUrl:(NSString *)url
{
    if ([url hasPrefix:@"http://"] || [url hasPrefix:@"https://"]) {
        return url;
    }
    return [NSString stringWithFormat:@"%@%@", HTTP_DOMAIN, url];
}


- (BOOL) handlerSuccess:(NSDictionary *)result
{
    //    NSString *errCode  =  result[@"error_code"];
    //    if([errCode isEqualToString:HTTP_ERROR_CODE_TOKEN] ||
    //       [errCode isEqualToString:HTTP_ERROR_CODE_UN_LOGIN] ||
    //       [errCode isEqualToString:HTTP_ERROR_CODE_SINGKEY_LOST] ){
    //        DSLog(@"errorMessage:%@", @"长时间未进行有效操作,请重新登录!");
    //        [[LoginDataMng sharedInstance] reLogin:^(BOOL success) {
    //        }];
    //        return NO;
    //    }else if([errCode isEqualToString:HTTP_ERROR_CODE_KICK]){
    //        [Toast loaded];
    //        DSLog(@"errorMessage:%@", @"您的账号在另一地点登录，您已被迫退出。如果不是您本人操作，您的密码可能已经泄露，建议您重新登录修改密码。");
    //        [AppUtils showErrorAlertByKick];
    //        return NO;
    //    }else if([errCode isEqualToString:HTTP_ERROR_CODE_PARAM_ERROR]){
    //        [Toast loaded];
    //        DSLog(@"errorMessage:%@", result[@"message"]);
    //        [AppUtils showErrorAlert:@"请求参数错误，请重新操作"];
    //        return NO;
    //    }
    NSString *message = result[@"message"];
    DSLog(@"errorMessage:%@", message);
    return YES;
}

@end
